﻿
using System;
using System.Collections.Generic;
using Refl.Extensions;

namespace Refl.Dreaming
{
    /// <summary>
    /// Provides ready to use Dream functionality, including the most commonly used assembly references and usings.
    /// </summary>
    public class Reverie : IDream
    {
        internal List<DreamError> _Errors
        {
            get { return _Engine._Errors; }
            set { _Engine._Errors = value; }
        }
        public List<DreamError> Errors
        {
            get { return _Engine._Errors; }
        }
        internal bool _HasErrors
        {
            get { return _Engine._HasErrors; }
            set { _Engine._HasErrors = value; }
        }
        public bool HasErrors
        {
            get { return _HasErrors; }
        }
        internal string _Name;
        public string Name
        {
            get { return _Name; }
        }
        internal bool _IsScript;
        public dynamic Info{get {return _Engine.Info;}set{_Engine.Info = value;}}
        internal dynamic _Engine; //Dreaming.Dream or Dreaming.Script
        /// <summary>
        /// Build a new Reverie receiving a String of code as argument.
        /// </summary>
        /// <param name="code">The string of code</param>
        /// <param name="language">The language in which the code is written. Defaults to Reflective-C#.</param>
        public Reverie(string code, Language language = Language.ReflectiveSharp)
        {
            if (language == Language.Brainfuck || language == Language.IronPython || language == Language.IronRuby
                || language == Language.JavaScript || language == Language.Lua)
            {
                _IsScript = true;
                _Engine = new Script(code, (ScriptLanguage)language);
                Info = new ScriptInfo();
                Info.Language = (ScriptLanguage)language;
            }
            else
            {
                _IsScript = false;
                _Engine = new Dream(code, (DreamLanguage)language);
                Info = new DreamInfo(DreamType.Reverie);
                Info.Language = (DreamLanguage)language;
            }
            
            UpdateName();
        }

        public bool Invoke()
        {
            return _Engine.Invoke();
        }
        public void InsertObject(string name, object obj)
        {
            _Engine.InsertObject(name, obj);
        }

        public dynamic RetrieveObject(string name)
        {
            return _Engine.RetrieveObject(name);
        }
        internal void UpdateName()
        {
            //the dream name is a MD5 hash of its characteristics.
            //TODO: Implement Json and generate a object for this.
            string assembled = (string.Format("[{0}][{1}][{2}]", _Engine._Str_Code, Info.Language.ToString(), Info.Threaded.ToString()));
            Info._Name = assembled.GetMD5Hash();
        }
    }
}
